import { nextTick, defineAsyncComponent, createApp, h, ref } from 'vue';
import type { App } from 'vue';
import * as svg from '@element-plus/icons-vue';
import router from '/@/router/index';
import pinia from '/@/stores/index';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import { i18n } from '/@/i18n';
import { Local } from '/@/utils/storage';
import { verifyUrl } from '/@/utils/toolsValidate';
import request from '/@/utils/request';
import ElementPlus, { ElConfigProvider } from 'element-plus';
import { ElDialog, ElDrawer, ElMessage } from 'element-plus';
import wtm from '/@/components/index';
import WtmButton from '/@/components/linkbutton/index.vue';
import { directive } from '/@/directive';

// 引入组件
const SvgIcon = defineAsyncComponent(() => import('/@/components/svgIcon/index.vue'));

/**
 * 导出全局注册 element plus svg 图标
 * @param app vue 实例
 * @description 使用：https://element-plus.gitee.io/zh-CN/component/icon.html
 */
export function elSvg(app: App) {
  const icons = svg as any;
  for (const i in icons) {
    app.component(`ele-${icons[i].name}`, icons[i]);
  }
  app.component('SvgIcon', SvgIcon);
}

/**
 * 设置浏览器标题国际化
 * @method const title = useTitle(); ==> title()
 */
export function useTitle() {
  const stores = useThemeConfig(pinia);
  const { themeConfig } = storeToRefs(stores);
  nextTick(() => {
    let webTitle = '';
    let globalTitle: string = themeConfig.value.globalTitle;
    const { path, meta } = router.currentRoute.value;
    if (path === '/login') {
      webTitle = <string>meta.title;
    } else {
      webTitle = setTagsViewNameI18n(router.currentRoute.value);
    }
    document.title = `${webTitle} - ${globalTitle}` || globalTitle;
  });
}

/**
 * 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化
 * @param params 路由 query、params 中的 tagsViewName
 * @returns 返回当前 tagsViewName 名称
 */
export function setTagsViewNameI18n(item: any) {
  let tagsViewName: string = '';
  const { query, params, meta } = item;
  // 修复tagsViewName匹配到其他含下列单词的路由
  // https://gitee.com/lyt-top/vue-next-admin/pulls/44/files
  const pattern = /^\{("(zh-cn|en|zh-tw)":"[^,]+",?){1,3}}$/;
  if (query?.tagsViewName || params?.tagsViewName) {
    if (pattern.test(query?.tagsViewName) || pattern.test(params?.tagsViewName)) {
      // 国际化
      const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName));
      tagsViewName = urlTagsParams[i18n.global.locale.value];
    } else {
      // 非国际化
      tagsViewName = query?.tagsViewName || params?.tagsViewName;
    }
  } else {
    // 非自定义 tagsView 名称
    tagsViewName = i18n.global.t(meta.title);
  }
  return tagsViewName;
}

/**
 * 图片懒加载
 * @param el dom 目标元素
 * @param arr 列表数据
 * @description data-xxx 属性用于存储页面或应用程序的私有自定义数据
 */
export const lazyImg = (el: string, arr: EmptyArrayType) => {
  const io = new IntersectionObserver((res) => {
    res.forEach((v: any) => {
      if (v.isIntersecting) {
        const { img, key } = v.target.dataset;
        v.target.src = img;
        v.target.onload = () => {
          io.unobserve(v.target);
          arr[key]['loading'] = false;
        };
      }
    });
  });
  nextTick(() => {
    document.querySelectorAll(el).forEach((img) => io.observe(img));
  });
};

/**
 * 全局组件大小
 * @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize`
 */
export const globalComponentSize = (): string => {
  const stores = useThemeConfig(pinia);
  const { themeConfig } = storeToRefs(stores);
  return Local.get('themeConfig')?.globalComponentSize || themeConfig.value?.globalComponentSize;
};

/**
 * 获取当前语言配置
 * @returns Element Plus 语言配置对象
 */
function getCurrentLocale() {
  // 从 i18n 实例获取当前语言配置
  const { messages, locale } = i18n.global;
  return (messages.value as any)[locale.value];
}

/**
 * 对象深克隆
 * @param obj 源对象
 * @returns 克隆后的对象
 */
export function deepClone(obj: EmptyObjectType) {
  let newObj: EmptyObjectType;
  try {
    newObj = obj.push ? [] : {};
  } catch (error) {
    newObj = {};
  }
  for (let attr in obj) {
    if (obj[attr] && typeof obj[attr] === 'object') {
      newObj[attr] = deepClone(obj[attr]);
    } else {
      newObj[attr] = obj[attr];
    }
  }
  return newObj;
}

export function setValue(oldObj: any, newObj: any) {
  for (let key in oldObj) {
    if (oldObj[key] && Array.isArray(oldObj[key]) == false && typeof oldObj[key] === 'object') {
      if (Object.hasOwn(newObj, key)) {
        setValue(oldObj[key], newObj[key]);
      } else {
        oldObj[key] = null;
      }
    } else {
      if (Object.hasOwn(newObj, key)) {
        oldObj[key] = newObj[key];
      } else {
        oldObj[key] = null;
      }
    }
  }
}

export function clearObj(oldObj: any) {
  for (let key in oldObj) {
    if (oldObj[key] && Array.isArray(oldObj[key]) == false && typeof oldObj[key] === 'object') {
      clearObj(oldObj[key]);
    } else {
      if (Array.isArray(oldObj[key])) {
        oldObj[key] = [];
      } else {
        oldObj[key] = null;
      }
    }
  }
}

/**
 * 判断是否是移动端
 */
export function isMobile() {
  if (
    navigator.userAgent.match(
      /('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i
    )
  ) {
    return true;
  } else {
    return false;
  }
}

/**
 * 判断数组对象中所有属性是否为空，为空则删除当前行对象
 * @description @感谢大黄
 * @param list 数组对象
 * @returns 删除空值后的数组对象
 */
export function handleEmpty(list: EmptyArrayType) {
  const arr = [];
  for (const i in list) {
    const d = [];
    for (const j in list[i]) {
      d.push(list[i][j]);
    }
    const leng = d.filter((item) => item === '').length;
    if (leng !== d.length) {
      arr.push(list[i]);
    }
  }
  return arr;
}

/**
 * 打开外部链接
 * @param val 当前点击项菜单
 */
export function handleOpenLink(val: RouteItem) {
  const { origin, pathname } = window.location;
  const linkUrl = <string>val.meta?.isLink;

  // 检查是否包含SsoLogin参数，如果包含则强制在新窗口打开
  const hasSsoLogin = linkUrl && (linkUrl.toLowerCase().includes('ssologin') || linkUrl.includes('SsoLogin'));
  if (hasSsoLogin) {
    // 包含SsoLogin参数的自定义菜单，直接在新窗口打开
    const token = Local.get('token');
    let finalUrl = linkUrl + '&access_token=' + token;
    window.open(finalUrl);
  } else {
    // 原有逻辑：先导航到路由，然后打开外部链接
    router.push(val.path);
    if (verifyUrl(linkUrl)) window.open(linkUrl);
    else window.open(`${origin}${pathname}#${linkUrl}`);
  }
}

export function downloadFile(data: Blob) {
  let filename = ``;
  let match = (<any>data)['contentDisposition'].match(/filename\*=UTF-8''(.+)$/i);
  if (match && match.length > 1) {
    filename = match[1];
  } else {
    match = (<any>data)['contentDisposition'].match(/filename\s*=\s*(.+);/i);
    if (match && match.length > 1) {
      filename = match[1];
    }
  }
  const href = URL.createObjectURL(data);
  const aLink = document.createElement('a');
  aLink.setAttribute('href', href);
  aLink.setAttribute('download', window.decodeURI(filename));
  aLink.click();
  aLink.remove();
}

export function getSelectList(url: string, ids: Array<number> | Array<string>, istree: boolean, action: string | undefined = undefined) {
  let m = 'get';
  if (action) {
    m = action;
  } else {
    if (ids && ids.length > 0) {
      m = 'post';
    }
  }
  let dd = [];
  if (Array.isArray(ids)) {
    dd = [...ids];
  } else {
    dd = [ids];
  }
  return request({
    url: url,
    method: m,
    data: dd,
  }).then((res) => {
    let rv: Array<any> = res.map((x: any) => x);
    return rv;
  });
}

export function setlectToTransfer(data: Array<any>) {
  return data.map((item: any) => {
    return {
      label: item.Text,
      key: item.Value,
    };
  });
}

export function setFormError(currentInstance: any, error: any) {
  try {
    for (let key in error.FormError) {
      let name = key.replace('.', '_') + '_FormItem';
      currentInstance.refs[name].validateState = 'error';
      currentInstance.refs[name].validateMessage = error.FormError[key];
    }
  } catch { /* empty */
  }
}

export function clearFormError(currentInstance: any) {
  try {
    for (let key in currentInstance.refs) {
      currentInstance.refs[key].validateState = 'valid';
      currentInstance.refs[key].validateMessage = null;
    }
  } catch { /* empty */
  }
}

export function openDialog(title: string, component: any, wtmdata: any, refreshFunc: any, width: any, customCallback?: (...args: any[]) => void, customButtons?: Array<{
  text: string,
  type?: string,
  onClick: () => void,
  visible?: boolean
}>) {
  const div = document.createElement('div');
  document.body.appendChild(div);

  // 样式已在 dialog-custom.scss 中定义，无需动态注入

  const close = () => {
    //@ts-ignore
    app.unmount(div);
    div.remove();
  };

  const app = createApp({
    setup() {
      // 使用 ref 创建响应式的按钮状态
      const componentHeaderButtons = ref<Array<{ text: string, type?: string, onClick: () => void }>>([]);

      // 更新头部按钮的方法
      const updateHeaderButtons = (buttons: Array<{ text: string, type?: string, onClick: () => void, visible?: boolean }>) => {
        componentHeaderButtons.value = buttons;
      };

      return {
        componentHeaderButtons,
        updateHeaderButtons,
      };
    },
    render() {
      // 合并自定义按钮和组件提供的按钮
      const allButtons = [...(customButtons || []), ...this.componentHeaderButtons];

      // 如果没有任何按钮，则不显示操作栏
      const finalButtons = allButtons;

      // 获取当前语言配置
      const currentLocale = getCurrentLocale();

      return h(ElConfigProvider, { locale: currentLocale }, () =>
        h(ElDialog, {
          draggable: true,
          modelValue: true,
          width: width || '70%',
          showClose: finalButtons.length === 0, // 当没有自定义按钮时显示关闭按钮
          closeOnClickModal: false,
          onClosed: () => {
            close();
          },
        }, {
          // 只有当有按钮时才显示自定义头部
          ...(finalButtons.length > 0 ? {
            header: () => h('div', {
              class: 'dialog-header-custom',
              style: 'display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 0 4px;'
            }, [
              // 标题
              h('span', {
                class: 'dialog-title-custom',
                style: 'font-size: 18px; font-weight: 500; color: var(--el-text-color-primary); line-height: 1.4;'
              }, title),
              // 按钮组
              h('div', {
                class: 'dialog-buttons-custom'
              }, finalButtons.filter(button => button.visible !== false).map(button =>
                h(WtmButton, {
                  icon: button.icon || '',
                  confirm: button.confirm || '',
                  type: button.type || 'info',
                  buttonText: button.text,
                  onClick: button.onClick,
                  class: 'dialog-action-btn'
                })
              ))
            ])
          } : {}),
          // 原始内容
          default: () => h(component, {
            ...(wtmdata !== null && wtmdata !== undefined ? { wtmdata: wtmdata } : {}),
            onCloseDialog: () => {
              close();
            },
            onRefresh: () => {
              if (refreshFunc) refreshFunc();
            },
            onUpdateHeaderButtons: this.updateHeaderButtons,
            // 事件透传：将submit事件绑定到customCallback
            onSubmit: (...args: any[]) => {
              if (typeof customCallback === 'function') {
                customCallback(...args);
              }
            }
          })
        })
      );
    },
  });

  directive(app);
  app.use(router).use(ElementPlus).use(i18n).use(wtm).mount(div);
}

export function openDrawer(title: string, component: any, wtmdata: any, refreshFunc: any, size: string) {
  const div = document.createElement('div');
  const close = () => {
    //@ts-ignore
    app.unmount(div);
    div.remove();
  };
  const app = createApp({
    render() {
      // 获取当前语言配置
      const currentLocale = getCurrentLocale();

      return h(ElConfigProvider, { locale: currentLocale }, () =>
        h(
          ElDrawer,
          {
            title: title,
            modelValue: true,
            size: size || '60%',
            withHeader: true,
            closeOnClickModal: false,
            closeOnPressEscape: true,
            showClose: true,
            destroyOnClose: true,
            modal: false, // 禁用遮罩层，避免阻止弹窗交互
            onClosed: () => {
              close();
            },
          },
          () =>
            h(component, {
              ...(wtmdata !== null && wtmdata !== undefined ? { wtmdata: wtmdata } : {}),
              onCloseDrawer: () => {
                close();
              },
              onRefresh: () => {
                if (refreshFunc) refreshFunc();
              },
            })
        )
      );
    },
  });
  directive(app);
  app.use(router).use(ElementPlus).use(i18n).use(wtm).mount(div);
}

export function flatTree(arr: any, intentkey: any = null, intent: number = 4) {
  if (arr.length <= 0) return false;
  for (let i = 0; i < arr.length; i++) {
    if (arr[i].children && arr[i].children.length > 0) {
      let temp = [...arr[i].children];
      if (intentkey !== null) {
        for (let j = 0; j < intent; j++) {
          temp.forEach((element) => {
            element[intentkey] = '-' + element[intentkey];
          });
        }
      }
      arr = arr.slice(0, i + 1).concat(temp, arr.slice(i + 1));
    }
  }
  return arr;
}

/**
 * 数据脱敏处理
 * @param type 脱敏类型：'phone' | 'bankCard' | 'idCard'
 * @param value 需要脱敏的值
 * @returns 脱敏后的字符串
 */
export function desensitize(type: 'phone' | 'bankCard' | 'idCard', value: string): string {
  if (!value) return '';

  value = value.toString();

  switch (type) {
    case 'phone':
      // 手机号：保留前3位和后4位
      return value.replace(/^(\d{3})\d*(\d{4})$/, '$1****$2');

    case 'bankCard':
      // 银行卡号：保留前4位和后4位
      return value.replace(/^(\d{4})\d*(\d{4})$/, '$1****$2');

    case 'idCard':
      // 身份证号：保留前4位和后4位
      return value.replace(/^(\d{4})\d*(\d{4})$/, '$1****$2');

    default:
      return value;
  }
}

/**
 * 根据身份证号码解析出生日期、性别、年龄
 * @param idCard 身份证号码
 * @returns 包含出生日期、性别、年龄的对象
 */
/**
 * 格式化身份证有效期显示
 * @param expiryDate 有效期字符串
 * @returns 格式化后的显示文本，超过50年显示"长期有效"
 */
export function formatIdCardExpiry(expiryDate: string | Date | null | undefined): string {
  if (!expiryDate) return '';

  const dateStr = String(expiryDate);
  if (/长期/.test(dateStr)) return '长期有效';

  // 简单粗暴：提取前4位年份，超过当前年份50年就是长期有效
  const year = parseInt(dateStr.substring(0, 4));
  return (year - new Date().getFullYear() > 50) ? '长期有效' : dateStr;
}

export function parseIdCard(idCard: string): {
  birthDate: Date | null;
  gender: string | null;
  age: number | null;
  valid: boolean;
  message?: string;
} {
  // 默认返回值
  const defaultResult = {
    birthDate: null,
    gender: null,
    age: null,
    valid: false,
    message: '身份证号码无效'
  };

  // 验证身份证号码
  if (!idCard || typeof idCard !== 'string') {
    return { ...defaultResult, message: '身份证号码不能为空' };
  }

  // 去除空格并转换为大写
  idCard = idCard.trim().toUpperCase();

  // 验证身份证号码长度和格式
  const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/;
  if (!idCardRegex.test(idCard)) {
    return { ...defaultResult, message: '身份证号码格式不正确' };
  }

  try {
    // 提取出生日期信息
    const year = parseInt(idCard.substring(6, 10));
    const month = parseInt(idCard.substring(10, 12));
    const day = parseInt(idCard.substring(12, 14));

    // 验证日期是否有效
    const birthDate = new Date(year, month - 1, day);
    if (birthDate.getFullYear() !== year ||
      birthDate.getMonth() !== month - 1 ||
      birthDate.getDate() !== day) {
      return { ...defaultResult, message: '身份证号码中的出生日期无效' };
    }

    // 验证出生日期是否在合理范围内
    const currentYear = new Date().getFullYear();
    if (year < 1900 || year > currentYear) {
      return { ...defaultResult, message: '身份证号码中的出生年份不在有效范围内' };
    }

    // 提取性别信息（第17位数字）
    const genderCode = parseInt(idCard.substring(16, 17));
    const gender = genderCode % 2 === 1 ? '男' : '女';

    // 计算年龄
    const today = new Date();
    let age = today.getFullYear() - year;

    // 检查是否还没过生日
    if (today.getMonth() < month - 1 ||
      (today.getMonth() === month - 1 && today.getDate() < day)) {
      age--;
    }

    // 验证年龄是否合理
    if (age < 0 || age > 150) {
      return { ...defaultResult, message: '计算出的年龄不在合理范围内' };
    }

    return {
      birthDate,
      gender,
      age,
      valid: true
    };

  } catch (error) {
    return { ...defaultResult, message: '解析身份证号码时发生错误' };
  }
}

/**
 * 手机号验证函数
 * @param rule 验证规则对象
 * @param value 要验证的手机号
 * @param callback 验证回调函数
 * @description 用于 Element Plus 表单验证，支持中国手机号格式验证
 */
export function validatePhone(rule: any, value: string, callback: any) {
  if (!value) {
    callback(); // 如果值为空，让 required 规则处理
    return;
  }

  // 中国手机号格式：11位数字，以1开头，第二位是3-9
  if (!/^1[3-9]\d{9}$/.test(value)) {
    callback(new Error('请输入正确的手机号码格式'));
    return;
  }

  callback();
}

/**
 * 增强的表单验证函数
 * @param formRef 表单引用
 * @param callback 验证成功后的回调函数
 * @param showDetailedErrors 是否显示详细的验证错误信息
 * @description 提供更好的用户体验，显示具体的验证错误信息
 */
export function validateFormWithMessage(formRef: any, callback: () => void, showDetailedErrors: boolean = true) {
  if (!formRef) {
    console.warn('表单引用不存在');
    return;
  }

  formRef.validate((valid: boolean, fields: any) => {
    if (valid) {
      // 验证通过，执行回调
      callback();
    } else if (showDetailedErrors && fields) {
      // 验证失败，显示详细错误信息
      // 遍历fields，收集所有字段的message
      const errorMessages: string[] = [];
      Object.keys(fields).forEach(fieldName => {
        const fieldErrors = fields[fieldName];
        if (fieldErrors && fieldErrors.length > 0) {
          // 获取第一个错误信息
          const firstError = fieldErrors[0];
          if (firstError && firstError.message) {
            errorMessages.push(firstError.message);
          }
        }
      });

      // 新增：合并所有错误信息
      if (errorMessages.length > 0) {
        ElMessage.error(errorMessages.join('，'));
      } else {
        ElMessage.error('请检查并完善表单中的必填项');
      }
    }
  });
}

/**
 * 计算工龄
 * @param startDate 开始日期，支持 Date 对象、时间戳或日期字符串
 * @param endDate 结束日期，默认为当前日期
 * @returns 包含年数、月数、天数、总天数的对象
 * @description 根据开始时间计算到指定日期的工龄，精确到天
 */
export function calculateWorkYears(startDate: Date | string | number, endDate: Date | string | number = new Date()) {
  // 统一转换为 Date 对象
  const startDateObj = new Date(startDate);
  const endDateObj = new Date(endDate);

  // 验证日期有效性
  if (isNaN(startDateObj.getTime()) || isNaN(endDateObj.getTime())) {
    return {
      years: 0,
      months: 0,
      days: 0,
      totalDays: 0,
      decimalYears: 0,
      formatted: '0年0月0天',
      valid: false,
      message: '日期格式无效'
    };
  }

  // 确保开始日期不晚于结束日期
  if (startDate > endDateObj) {
    return {
      years: 0,
      months: 0,
      days: 0,
      totalDays: 0,
      decimalYears: 0,
      formatted: '0年0月0天',
      valid: false,
      message: '入职日期不能晚于结束日期'
    };
  }

  // 计算总天数
  const timeDiff = endDateObj.getTime() - startDateObj.getTime();
  const totalDays = Math.floor(timeDiff / (1000 * 60 * 60 * 24));

  // 计算年、月、日
  let years = endDateObj.getFullYear() - startDateObj.getFullYear();
  let months = endDateObj.getMonth() - startDateObj.getMonth();
  let days = endDateObj.getDate() - startDateObj.getDate();

  // 处理月份和日期的进位
  if (days < 0) {
    months--;
    // 获取上个月的天数
    const lastMonth = new Date(endDateObj.getFullYear(), endDateObj.getMonth(), 0);
    days += lastMonth.getDate();
  }

  if (months < 0) {
    years--;
    months += 12;
  }

  // 计算精确的小数年份 (保留1位小数)
  // 方法：总年份 + (月份/12) + (天数/365.25)
  const decimalYears = parseFloat((years + months / 12 + days / 365.25).toFixed(1));

  // 格式化输出 - 优化显示效果，只显示非零部分
  let formatted = '';
  if (years > 0) {
    formatted += `${years}年`;
  }
  if (months > 0) {
    formatted += `${months}月`;
  }
  if (days > 0) {
    formatted += `${days}天`;
  }

  // 如果所有值都为0，显示"0天"
  if (formatted === '') {
    formatted = '0天';
  }

  return {
    years,
    months,
    days,
    totalDays,
    decimalYears, // 新增精确小数年份
    formatted,
    valid: true,
    message: '计算成功'
  };
}

/**
 * 统一批量导出
 * @method elSvg 导出全局注册 element plus svg 图标
 * @method useTitle 设置浏览器标题国际化
 * @method setTagsViewNameI18n 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化
 * @method lazyImg 图片懒加载
 * @method globalComponentSize() element plus 全局组件大小
 * @method deepClone 对象深克隆
 * @method isMobile 判断是否是移动端
 * @method handleEmpty 判断数组对象中所有属性是否为空，为空则删除当前行对象
 * @method handleOpenLink 打开外部链接
 * @method downloadFile 下载文件
 * @method getSelectList 获取选择列表数据
 * @method setlectToTransfer 转换选择数据为穿梭框格式
 * @method setValue 设置对象值
 * @method setFormError 设置表单错误信息
 * @method clearFormError 清除表单错误信息
 * @method clearObj 清除对象值
 * @method openDialog 打开对话框，支持自定义头部按钮
 * @method openDrawer 打开抽屉组件
 * @method flatTree 扁平化树形数据
 * @method desensitize 数据脱敏处理
 * @method parseIdCard 根据身份证号码解析出生日期、性别、年龄
 * @method validatePhone 手机号验证函数，用于 Element Plus 表单验证
 * @method validateFormWithMessage 增强的表单验证函数，提供详细的错误提示
 * @method calculateWorkYears 计算工龄，根据入职时间计算到指定日期的工龄
 */
const other = {
  elSvg: (app: App) => {
    elSvg(app);
  },
  useTitle: () => {
    useTitle();
  },
  setTagsViewNameI18n(route: RouteToFrom) {
    return setTagsViewNameI18n(route);
  },
  lazyImg: (el: string, arr: EmptyArrayType) => {
    lazyImg(el, arr);
  },
  globalComponentSize: () => {
    return globalComponentSize();
  },
  deepClone: (obj: EmptyObjectType) => {
    return deepClone(obj);
  },
  isMobile: () => {
    return isMobile();
  },
  handleEmpty: (list: EmptyArrayType) => {
    return handleEmpty(list);
  },
  handleOpenLink: (val: RouteItem) => {
    handleOpenLink(val);
  },
  downloadFile: (data: Blob) => {
    downloadFile(data);
  },
  getSelectList: (url: string, ids: Array<number> | Array<string>, istree: boolean, action: string | undefined = undefined) => {
    return getSelectList(url, ids, istree, action);
  },
  setlectToTransfer: (data: Array<any>) => {
    return setlectToTransfer(data);
  },
  setValue(oldObj: any, newObj: any) {
    setValue(oldObj, newObj);
  },
  setFormError(currentInstance: any, error: any) {
    setFormError(currentInstance, error);
  },
  clearFormError(currentInstance: any) {
    clearFormError(currentInstance);
  },
  clearObj(oldObj: any) {
    clearObj(oldObj);
  },
  openDialog(title: string, component: any, wtmdata: any = null, refreshFunc: any = null, width: any = null, customCallback?: (...args: any[]) => void, customButtons?: Array<{
    text: string,
    type?: string,
    onClick: () => void,
    visible?: boolean
  }>) {
    openDialog(title, component, wtmdata, refreshFunc, width, customCallback, customButtons);
  },
  openDrawer(title: string, component: any, wtmdata: any = null, refreshFunc: any = null, size: any = null) {
    openDrawer(title, component, wtmdata, refreshFunc, size);
  },
  flatTree(arr: any, intentkey: any = null, intent: number = 2): any[] {
    return flatTree(arr, intentkey, intent);
  },
  desensitize: (type: 'phone' | 'bankCard' | 'idCard', value: string) => {
    return desensitize(type, value);
  },
  parseIdCard: (idCard: string) => {
    return parseIdCard(idCard);
  },
  validatePhone: (rule: any, value: string, callback: any) => {
    return validatePhone(rule, value, callback);
  },
  validateFormWithMessage: (formRef: any, callback: () => void, showDetailedErrors: boolean = true) => {
    return validateFormWithMessage(formRef, callback, showDetailedErrors);
  },
  calculateWorkYears: (hireDate: Date | string | number, endDate: Date | string | number = new Date()) => {
    return calculateWorkYears(hireDate, endDate);
  },
  formatIdCardExpiry: (expiryDate: string | Date | null | undefined) => {
    return formatIdCardExpiry(expiryDate);
  },
};

// 统一批量导出
export default other;
